package com.dotandmedia.action;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;

import com.dotmedia.dboperations.RoleDatabaseOperations;
import com.dotmedia.dboperations.UserDatabaseOperations;
import com.dotmedia.entities.Role;
import com.dotmedia.entities.User;
import com.dotmedia.utils.StringUtils;
import com.opensymphony.xwork2.ActionSupport;

/**
 * This class is the action class for the user list. This action class will get all the roles in the system and the corresponding users. It will then
 * form a JSON string from the same and then pass it to the view page.
 * 
 * This Action expects two input parameters which can be null. If they are null then it will default to the normal implementation. The input
 * parameters expected are -
 * 
 * user - The user name like which is to be queried from the database active - Indicates whether we have to search active, inactive or both types of
 * users. It can be active / inactive / both
 * 
 * @author siddharthsaha
 * 
 */
public class UserListAction extends ActionSupport implements SessionAware, ServletRequestAware, ServletResponseAware {

	private static String ACTIVE_USERS = "active";
	private static String INACTIVE_USERS = "inactive";
	private static String BOTH_USERS = "both";

	private static Logger logger = Logger.getLogger("UserListAction");

	private static String LOGGED_ON = "logged.on";
	private static String ADMIN_LOGGED_ON = "admin.logged.on";
	private static String NOT_LOGGED_ON = "not.logged.on";

	protected Map session;
	protected HttpServletRequest request;
	protected HttpServletResponse response;

	private String user; // the user name submitted to this Action
	private String active; // can be active / inactive / both

	@Override
	public void setServletResponse(HttpServletResponse resp) {
		this.response = resp;
	}

	@Override
	public void setServletRequest(HttpServletRequest req) {
		this.request = req;
	}

	@Override
	public void setSession(Map session) {
		this.session = session;
	}

	// Getters and setters for variables
	public void setUser(String user) {
		this.user = user;
	}

	public String getUser() {
		return user;
	}

	public void setActive(String active) {
		this.active = active;
	}

	public String getActive() {
		return active;
	}

	/**
	 * This method will get the information from the database and form a JSON string and then send it to the view
	 * 
	 * @return
	 */
	public String executeUserListAction() {
		logger.info("IN method executeUserListAction in UserListAction");
		if (session.containsKey(LOGGED_ON)) {
			if (session.get(LOGGED_ON).equals(ADMIN_LOGGED_ON)) {
				logger.info("Getting all Roles from the database");
				Date currentDate = new Date();
				if (StringUtils.isStringNull(active)) {
					logger.info("Active input parameter was null. Defaulting to both");
					active = BOTH_USERS;
				} else if (!active.equals(ACTIVE_USERS) && !active.equals(INACTIVE_USERS)) {
					logger.error("Active input is not a valid input. Defaulting to both");
					active = BOTH_USERS;
				}
				Map<String, Object> infoMap = new HashMap<String, Object>(); // this is the info map
				RoleDatabaseOperations roleDatabaseOperations = new RoleDatabaseOperations();
				List<Role> roleEntities = roleDatabaseOperations.getAllRoleEntities();
				UserDatabaseOperations userDatabaseOperations = new UserDatabaseOperations();
				for (int roleEntitiesIndex = 0; roleEntitiesIndex < roleEntities.size(); roleEntitiesIndex++) {
					Role currentRoleEntity = roleEntities.get(roleEntitiesIndex);
					logger.info("Getting the user for the Role: " + currentRoleEntity.getRoleExtId());
					List<User> userEntities = userDatabaseOperations.getUsersWithRoleExtId(currentRoleEntity.getRoleExtId());
					Map<String, Object> userEntitesMap = new HashMap<String, Object>();
					for (int userEntitiesIndex = 0; userEntitiesIndex < userEntities.size(); userEntitiesIndex++) {
						User currentUserEntity = userEntities.get(userEntitiesIndex);
						boolean isActive = false;
						String username = currentUserEntity.getName() + " " + currentUserEntity.getSurname();
						boolean toInclude = false; // indicated whether we have to include this user or not
						if (!StringUtils.isStringNull(user)) {
							// we need to compare for the user name and include it only if it matches
							if (username.contains(user)) {
								// this can be included - check for date
								if ((currentDate.getTime() - currentUserEntity.getExpireOn().getTime()) < 0) {
									// this user is active
									if (active.equals(BOTH_USERS) || active.equals(ACTIVE_USERS)) {
										// include this user
										logger.info("User is included. User Ext id: " + currentUserEntity.getUserExtId());
										isActive = true;
										toInclude = true;
									}
								} else {
									// this user is inactive
									if (active.equals(BOTH_USERS) || active.equals(INACTIVE_USERS)) {
										logger.info("User is included. User Ext id: " + currentUserEntity.getUserExtId());
										toInclude = true;
										isActive = false;
									}
								}
							}
						} else {
							if ((currentDate.getTime() - currentUserEntity.getExpireOn().getTime()) < 0) {
								// this user is active
								if (active.equals(BOTH_USERS) || active.equals(ACTIVE_USERS)) {
									// include this user
									logger.info("User is included. User Ext id: " + currentUserEntity.getUserExtId());
									toInclude = true;
									isActive = true;
								}
							} else {
								// this user is inactive
								if (active.equals(BOTH_USERS) || active.equals(INACTIVE_USERS)) {
									logger.info("User is included. User Ext id: " + currentUserEntity.getUserExtId());
									toInclude = true;
									isActive = false;
								}
							}
						}
						if (toInclude) {
							// include this user in the map
							Map<String, Object> currentUserMap = new HashMap<String, Object>();
							currentUserMap.put("name", currentUserEntity.getName());
							currentUserMap.put("surname", currentUserEntity.getSurname());
							currentUserMap.put("userExtId", currentUserEntity.getUserExtId());
							currentUserMap.put("langCode", currentUserEntity.getUiTranslation().getLangCode());
							currentUserMap.put("password", currentUserEntity.getPassword());
							currentUserMap.put("role", currentUserEntity.getRole().getRoleExtId());
							currentUserMap.put("userId", currentUserEntity.getId());
							Date expiryDate = currentUserEntity.getExpireOn();
							DateFormat simpleDateFormat = new SimpleDateFormat("MM/dd/yyyy");
							String formattedDate = simpleDateFormat.format(expiryDate);
							currentUserMap.put("expiryDate", formattedDate);
							currentUserMap.put("status", isActive);
							userEntitesMap.put(currentUserEntity.getEmail(), currentUserMap);
						}
					}
					infoMap.put(currentRoleEntity.getRoleExtId(), userEntitesMap);
				}
				request.setAttribute("userListMap", infoMap);
				logger.info("OUT method executeUserListAction is UserListAction");
				return SUCCESS;
			} else {
				return NOT_LOGGED_ON;
			}
		} else {
			return NOT_LOGGED_ON;
		}
	}
}
